package controller

import (
	"bytes"
	"encoding/binary"
	"fabric-explorer/tools"
	"fmt"
	"net/http"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
)

const (
	tokenName = "gin_cookie"
)

//用户
type User struct {
	userName string
	password string
}

//管理员
var admin = &User{userName: "admin", password: "adminpw"}
var sessionMap map[string]string

func init() {
	sessionMap = make(map[string]string)
}

//登录
func Login(c *gin.Context) {
	userName := c.DefaultQuery("userName", "")
	if userName == "" {
		userName = c.Request.FormValue("userName")
	}
	password := c.DefaultQuery("password", "")
	if password == "" {
		password = c.Request.FormValue("password")
	}
	passwordSha256 := tools.Sha256Encoding([]byte(admin.password))
	if userName == admin.userName && password == passwordSha256 {
		//随机生成token
		now := time.Now().UnixMilli()
		x := int32(now)
		bytesBuffer := bytes.NewBuffer([]byte{})
		binary.Write(bytesBuffer, binary.BigEndian, x)
		token := tools.Sha256Encoding(bytesBuffer.Bytes())
		c.SetCookie(tokenName, token, 0, "/", "", false, true)
		sessionMap[token] = admin.userName
		tools.SuccessResult(c, "success")
		fmt.Printf("admin登录成功，token:%s\n", token)
		return
	}
	tools.FailResult(c, "login fail")
}

//登出
func LoginOut(c *gin.Context) {
	s, err := c.Cookie(tokenName)
	if err != nil || s == "" {
		tools.FailResult(c, "")
		return
	} else {
		delete(sessionMap, s)
	}
	tools.SuccessResult(c, "")
}

//检测登录状态
func GetToken(c *gin.Context) {
	s, err := c.Cookie(tokenName)
	userName := sessionMap[s]
	if err != nil || s == "" || userName == "" {
		tools.FailResult(c, "")
		return
	}
	tools.SuccessResult(c, "")
}

// http 请求拦截器
func ApiInterceptor() gin.HandlerFunc {
	return func(c *gin.Context) {
		fmt.Printf("c.Request.URL: %v\n", c.Request.URL)
		ifLoginUrl := strings.Contains(c.Request.RequestURI, "login")
		if ifLoginUrl {
			c.Next()
			return
		}
		ifTokenUrl := strings.Contains(c.Request.RequestURI, "token")
		if ifTokenUrl {
			c.Next()
			return
		}
		s, err := c.Cookie(tokenName)
		if err != nil || s == "" {
			fmt.Printf("未登录,ip:%s\n", c.RemoteIP())
			// 验证不通过，不再调用后续的函数处理
			c.Abort()
			c.JSON(http.StatusUnauthorized, gin.H{
				"Data":    401,
				"Message": "访问未授权",
				"success": false,
			})
			return
		}
		// 执行下一个
		c.Next()
	}
}

// http 请求拦截器
func CorsInterceptor() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 执行下一个
		c.Next()
		c.Header("Access-Control-Allow-Origin", "*")
		c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT")
		c.Header("Access-Control-Max-Age", "3600")
	}
}
